﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Threading;
namespace ModbusBase
{
    internal class Program
    {
        static void Main(string[] args)
        {
           SerialPort serialPort = new SerialPort();

            //设置属性：96N81
            serialPort.PortName = "COM5";//主站设备串口端口
            #region 查看主站设备使用的端口号
//            右键点击 "此电脑"，选择 "管理" → "设备管理器"。
//展开 "端口（COM 和 LPT）"，列表中显示的 COM 端口即为设备使用的端口号（如COM5）。
            #endregion
            //波特率
            serialPort.BaudRate = 9600;
            serialPort.Parity = Parity.None;
            //数据位长度
            serialPort.DataBits = 8;
            serialPort.StopBits = StopBits.One;

            //打开串口
            serialPort.Open();

            while (true)
            {
                Thread.Sleep(2000);
                //拼接报文
                List<byte> sendBtyes = new List<byte>();
                //从站地址 0x01
                sendBtyes.Add(0x01);
                //功能码 0x03
                sendBtyes.Add(0x03);
                //起始寄存器（高位） 0x00
                sendBtyes.Add(0x00);
                //起始寄存器（低位） 0x00
                sendBtyes.Add(0x00);
                //寄存器数量（高位） 0x00
                sendBtyes.Add(0x00);
                //寄存器数量（低位） 0x02
                sendBtyes.Add(0x02);
                //CRC校验 0xC40B
                sendBtyes.Add(0xC4);
                sendBtyes.Add(0x0B);

                //发送报文
                serialPort.Write(sendBtyes.ToArray(), 0, sendBtyes.Count);

                Thread.Sleep(100);//需要一定的延时

                //接受报文
                byte[] receiveBytes = new byte[serialPort.BytesToRead];
                //接受缓冲区全部的字节
                serialPort.Read(receiveBytes, 0, receiveBytes.Length);

                if (receiveBytes[0] == 0x01)//简单的判断
                {
                    //观察报文：01 03 04 00  7B 02  4D 4B 7F（原报文是16进制）
                    //接收报文： 1 3  4  00 123  2  77 75 127
                    //数据索引：[0][1][2][3][4][5] [6] [7] [8]
                    //字节到10进制高低位转换：     123=（123/256)+(123%256)
                    //                                      0         123
                    //                              589 = (589/256)+(589%256)
                    //                                         2        77
                    //                                 2*256+77=589
                    //转换成湿度、温度：（1个高字节=256，所以，高位的要乘以256+低位）
                    int humidity = receiveBytes[3] * 256 + receiveBytes[4];
                    int temperature = receiveBytes[5] * 256 + receiveBytes[6];
                    Console.WriteLine($"湿度：{humidity * 0.1}% 温度：{temperature * 0.1}℃");
                }
            }
        }
    }
}
